<template>
  <div id="windowIssueParseManage">
    <el-input v-model="$store.state.obj_setting_map.access_token" disabled placeholder="AccessToken"/>
    <el-input
        v-model="issue_keyword_list"
        :autosize="{ minRows: 4, maxRows: 10 }"
        type="textarea"
        placeholder="输入CVE编号，一行一个（`#`进行注释，空行自动跳过）"
        style="margin-top: 8px"
    />
    <el-button style="width: 100%; margin-top: 5px" type="primary" plain @click="cve_keyword_parse"
               v-loading="loading_search_issue">开始分析
    </el-button>

    <el-descriptions v-for="(v, k) in cve_info_list" :key="k" :column="4" v-loading="v.loading"
                     size="default" border style="margin-top: 10px">
      <el-descriptions-item label="CVE编号" :span="1"><strong>{{ v.title }}</strong></el-descriptions-item>
      <el-descriptions-item label="软件包名" :span="1">{{ v.rpm_name }}
        <el-button @click="do_copy('https://gitee.com/src-openeuler/' + v.rpm_name + '.git')" type="info" plain
                   size="small">复制Git链接
        </el-button>
      </el-descriptions-item>
      <el-descriptions-item label="Gitee链接" :span="2">
        <el-link type="success" :href="v.html_url" target="_blank">{{ v.html_url }}</el-link>
      </el-descriptions-item>
      <el-descriptions-item label="创建时间" :span="1">{{ get_format_time(v.created_at) }}</el-descriptions-item>
      <el-descriptions-item label="关闭时间" :span="1">{{ get_format_time(v.finished_at) }}</el-descriptions-item>
      <el-descriptions-item label="NVD链接" :span="2">
        <el-link type="success" :href="v.nvd_link" target="_blank">{{ v.nvd_link }}</el-link>
      </el-descriptions-item>
      <el-descriptions-item label="CVSS" :span="2"> {{ v.cvss }}
        <el-button @click="do_copy(v.cvss)" type="success" plain size="small">
          <el-icon>
            <DocumentCopy/>
          </el-icon>
        </el-button>
      </el-descriptions-item>
      <el-descriptions-item label="BaseScore" :span="1"> {{ v.base_score }}</el-descriptions-item>
      <el-descriptions-item label="修复状态" :span="1">{{ v.issue_state }}</el-descriptions-item>
      <el-descriptions-item label="日志匹配" :span="4">
        <el-radio-group v-model="v.branch_choice" @change="git_spec_from_gitee(v.rpm_name, v.branch_choice, v.title)">
          <el-radio-button label="master"/>
          <el-radio-button label="openEuler-20.03-LTS"/>
          <el-radio-button label="openEuler-20.03-LTS-SP1"/>
          <el-radio-button label="openEuler-20.03-LTS-SP2"/>
          <el-radio-button label="openEuler-20.03-LTS-SP3"/>
        </el-radio-group>
        <div v-html="v.changelog_parse" v-loading="v.changelog_parse==='加载中。。。'"></div>
        <div v-if="v.changelog_str!==''">
          <el-link type="success" @click="show_all_spec(v.changelog_str, '所有日志：' + v.rpm_name)">显示所有日志
            <el-icon class="el-icon--right">
              <Search/>
            </el-icon>
          </el-link>
        </div>
        <div v-if="v.SPEC_str!==''">
          <el-link type="warning" @click="show_all_spec(v.SPEC_str, '整个SPEC：' + v.rpm_name)">显示整个SPEC
            <el-icon class="el-icon--right">
              <Search/>
            </el-icon>
          </el-link>
        </div>
      </el-descriptions-item>
      <!--      <el-descriptions-item label="SPEC" :span="4">-->
      <!--        &lt;!&ndash;        <el-input v-model="v.SPEC_str" v-loading="v.is_loading_spec" :autosize="{ minRows: 2, maxRows: 40 }"&ndash;&gt;-->
      <!--        &lt;!&ndash;                  type="textarea" placeholder="显示SPEC数据"/>&ndash;&gt;-->
      <!--        <windowCodeMirrorComponent :editFileStr="v.SPEC_str" :height="500"></windowCodeMirrorComponent>-->
      <!--      </el-descriptions-item>-->
    </el-descriptions>
  </div>
</template>

<script>
import axios from 'axios'
import {ElNotification} from 'element-plus'
import {Search, DocumentCopy} from '@element-plus/icons-vue'

export default {
  name: "windowIssueParseManage",
  props: {
    sessionToken: String,
    codeName: String,
    height: Number
  },
  components: {Search, DocumentCopy},
  data() {
    return {
      accessToken: "",
      form_function_choice: {},
      loading_search_issue: false,
      issue_keyword_list: "",
      cve_keyword_list: [],
      cve_info_list: {}
    }
  },
  methods: {
    do_copy(copy_str) {
      this.$copyText(copy_str).then(function () {
        ElNotification({
          title: '复制成功',
          type: 'success',
        })
      }, function () {
        ElNotification({
          title: '复制失败',
          type: 'error',
        })
      })
    },
    get_format_time(time_str) {
      let date = new Date(time_str);
      let year = date.getFullYear(),
          month = date.getMonth() + 1,
          day = date.getDate()//,
      // hour = date.getHours(),
      // min = date.getMinutes(),
      // sec = date.getSeconds();
      return year + '-' + month + '-' + day // + ' ' + hour + ':' + min + ':' + sec;
    },
    get_nvd_link_from_body(body) {
      return /((?:http(s)?:\/\/)nvd\.nist\.gov\/vuln\/detail\/CVE-\d+-\d+)/i.exec(body)[1].trim()
    },
    get_cvss_from_body(body) {
      return /Vector[：:]([Cc][Vv][Ss]{2}[：:].*)\n/.exec(body)[1].trim().replace("：", ":")
    },
    get_base_score_from_body(body) {
      return /BaseScore[：:]+(.*)\n/i.exec(body)[1].trim()//.replace("：", ":")
    },
    single_issue_parse(issue_info) {
      console.log(issue_info)
      issue_info.rpm_name = /https:\/\/gitee\.com\/src-openeuler\/(.*)\/issues\/.*/.exec(issue_info.html_url)[1].trim()
      issue_info.is_loading_spec = true
      issue_info.SPEC_str = ""
      issue_info.changelog_str = ""
      issue_info.changelog_parse = ""
      issue_info.branch_choice = "" //"openEuler-20.03-LTS-SP1"
      issue_info.cvss = this.get_cvss_from_body(issue_info.body)
      issue_info.base_score = this.get_base_score_from_body(issue_info.body)
      issue_info.nvd_link = this.get_nvd_link_from_body(issue_info.body)
      issue_info.koji_parse = "<h3>仓库软件包版本分析中...</h3>"
      issue_info.koji_parse_loading = true
      this.cve_info_list[issue_info.title] = issue_info
      // this.git_spec_from_gitee(issue_info.rpm_name, "openEuler-20.03-LTS-SP1", issue_info.title) // 默认不触发
    },
    get_issue_info_by_keyword(keyword) {
      let obj_this = this
      obj_this.loading_issue_info = true
      let accessToken = this.$store.state.obj_setting_map.access_token
      let url = "https://gitee.com/api/v5/search/issues?access_token=" + accessToken + "&q=" + keyword + "&page=1&per_page=100&order=desc"
      axios.get(url).then(function (response) {
        for (let i = 0; i < response.data.length; i++) {
          if (response.data[i].html_url.startsWith("https://gitee.com/src-openeuler")) {
            obj_this.single_issue_parse(response.data[i])
          }
        }
      }).catch(function (error) { // 请求失败处理
        console.log(error);
        ElNotification({
          title: "GiteeAPI请求失败",
          type: 'error',
        })
      });
    },
    get_change_log_from_spec(spec_str) {
      return spec_str.split("%changelog")[1]
    },
    get_change_log_parse(changelog_str, CVE_title) {
      let changelog_one_list = changelog_str.split('*')
      for (let i = 0; i < changelog_one_list.length; i++) {
        let change_one = '*' + changelog_one_list[i]
        change_one = change_one.replace(/^\s+|\s+$/g, '')
        if (change_one.includes(CVE_title)) {
          change_one = change_one.replaceAll(CVE_title, "<span style='color: red'>" + CVE_title + "</span>")
          change_one = change_one.replaceAll("\n", "<br/>")
          return change_one
        }
      }
      return "<h5>日志分析失败，未匹配到相关CVE</h5>"
    },
    change_log_parse_branch_change(branch) {
      console.log(branch)
    },
    get_spec_blob(spec_blob_url, CVE_title) {
      let obj_this = this
      axios.get(spec_blob_url).then(function (response) {
        let spec_str = window.atob(response.data.content)
        obj_this.cve_info_list[CVE_title].SPEC_str = spec_str
        obj_this.cve_info_list[CVE_title].changelog_str = obj_this.get_change_log_from_spec(spec_str)
        obj_this.cve_info_list[CVE_title].changelog_parse = obj_this.get_change_log_parse(obj_this.cve_info_list[CVE_title].changelog_str, CVE_title)
        obj_this.cve_info_list[CVE_title].is_loading_spec = false
      }).catch(function (error) { // 请求失败处理
        console.log(error);
        obj_this.cve_info_list[CVE_title].is_loading_spec = false
        obj_this.cve_info_list[CVE_title].SPEC_str = "加载失败"
        obj_this.cve_info_list[CVE_title].changelog_parse = "<h5>日志分析失败（请求过于频繁）</h5>"
      });
    },
    git_spec_from_gitee(codeName, branch_choice, CVE_title) {
      // 获取所有文件：https://gitee.com/api/v5/repos/src-openeuler/libwd/git/trees/openEuler-20.03-LTS-SP1
      let obj_this = this
      obj_this.cve_info_list[CVE_title].changelog_parse = "加载中。。。"
      obj_this.form_function_choice.is_code_name_lock = true
      let accessToken = this.$store.state.obj_setting_map.access_token
      let url = "https://gitee.com/api/v5/repos/src-openeuler/" + codeName + "/git/trees/" + branch_choice +
          "?access_token=" + accessToken
      axios.get(url).then(function (response) {
        let file_list = response.data.tree
        for (let i = 0; i < file_list.length; i++) {
          if (file_list[i].path.endsWith(".spec")) {
            obj_this.get_spec_blob(file_list[i].url, CVE_title)
            break
          }
        }
      }).catch(function (error) { // 请求失败处理
        console.log(error);
        ElNotification({title: "GiteeAPI请求失败，重新获取授权码", type: 'error',})
      });
    },
    show_all_spec(file_str, title) {
      this.$store.state.obj_windowEditorManage.addTab_code_mirror_page_out(file_str, title)
    },
    cve_keyword_parse() {
      if (this.issue_keyword_list === "") return
      this.cve_keyword_list = this.issue_keyword_list.split('\n')
      this.cve_info_list = {}
      this.issue_keyword_list = ""
      for (let i = 0; i < this.cve_keyword_list.length; i++) {
        console.log("ssss", this.cve_keyword_list[i])
        if (/^[Cc][Vv][Ee]-\d+-\d+$/.test(this.cve_keyword_list[i])) {
          this.cve_info_list[this.cve_keyword_list[i]] = {"loading": true}
          this.get_issue_info_by_keyword(this.cve_keyword_list[i])
          console.log(this.cve_keyword_list[i])
        }
      }
    },
  },
  mounted() {
  }
}
</script>

<style scoped>
#windowIssueParseManage {
  padding: 10px;
}

ul {
  margin-block-start: 0;
  margin-block-end: 0;
  margin-inline-start: 0px;
  margin-inline-end: 0px;
  padding-inline-start: 0;
}
</style>
